package miao.byusi.termux.gui.utils;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Shell命令执行工具类
 * 提供Termux环境下的命令执行和环境检测功能
 */
public class ShellUtils {
    private static final Logger logger = LoggerFactory.getLogger(ShellUtils.class);
    
    // Termux环境特征路径
    private static final String[] TERMUX_PATHS = {
        "/data/data/com.termux/files/usr",
        "/data/data/com.termux/files/home",
        "/data/data/com.termux/files/usr/bin/login"
    };

    /**
     * 执行Shell命令并返回输出结果
     * @param command 要执行的命令
     * @return 命令输出内容（自动trim）
     * @throws IOException 如果执行失败或返回非0状态码
     */
    public static String executeCommand(String command) throws IOException {
        if (command == null || command.trim().isEmpty()) {
            throw new IllegalArgumentException("命令不能为空");
        }

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        CommandLine commandline = CommandLine.parse(command);
        DefaultExecutor exec = new DefaultExecutor();
        PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
        exec.setStreamHandler(streamHandler);
        
        try {
            logger.debug("执行命令: {}", command);
            int exitValue = exec.execute(commandline);
            String result = outputStream.toString().trim();
            
            if (exitValue != 0) {
                logger.warn("命令执行返回非零状态: {} | 命令: {}", exitValue, command);
                throw new IOException("命令执行失败 (退出码: " + exitValue + "): " + command);
            }
            
            logger.debug("命令输出: {}", result);
            return result;
        } catch (IOException e) {
            logger.error("命令执行失败: {} | 错误: {}", command, e.getMessage());
            throw new IOException("执行命令失败: " + command, e);
        }
    }

    /**
     * 检测是否在Termux环境中运行
     * @return true如果是Termux环境，否则false
     */
    public static boolean isTermuxEnvironment() {
        try {
            // 方法1：检查环境变量
            String prefix = System.getenv("PREFIX");
            if (prefix != null && prefix.contains("com.termux")) {
                return true;
            }

            // 方法2：检查Termux特征路径
            for (String path : TERMUX_PATHS) {
                if (new File(path).exists()) {
                    return true;
                }
            }

            // 方法3：检查特定Termux命令
            String termuxProp = executeCommand("termux-info 2>/dev/null || echo ''");
            if (!termuxProp.isEmpty()) {
                return true;
            }

            return false;
        } catch (Exception e) {
            logger.warn("环境检测异常: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 获取Termux环境信息（诊断用）
     * @return 包含环境信息的Map
     */
    public static Map<String, String> getTermuxEnvInfo() {
        Map<String, String> info = new HashMap<>();
        try {
            info.put("PREFIX", System.getenv("PREFIX"));
            info.put("HOME", System.getenv("HOME"));
            info.put("PATH", System.getenv("PATH"));
            
            // 检查关键文件
            for (String path : TERMUX_PATHS) {
                info.put("FILE_" + path.replace("/", "_"), 
                    new File(path).exists() ? "EXISTS" : "MISSING");
            }
            
            // 检查命令可用性
            String[] testCommands = {"pkg", "Xvfb", "x11vnc", "fluxbox"};
            for (String cmd : testCommands) {
                info.put("CMD_" + cmd, 
                    executeCommand("which " + cmd + " 2>/dev/null || echo 'NOT_FOUND'"));
            }
            
        } catch (Exception e) {
            logger.error("获取环境信息失败", e);
            info.put("ERROR", e.getMessage());
        }
        return info;
    }

    /**
     * 检查命令是否可用
     * @param command 要检查的命令
     * @return true如果命令可用
     */
    public static boolean isCommandAvailable(String command) {
        try {
            String path = executeCommand("which " + command + " 2>/dev/null");
            return !path.isEmpty() && !path.contains("not found");
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 执行命令并允许输出到控制台（不捕获输出）
     */
    public static void executeCommandWithOutput(String command) throws IOException {
        CommandLine commandline = CommandLine.parse(command);
        DefaultExecutor exec = new DefaultExecutor();
        exec.execute(commandline);
    }
}